package com.example.screen.record;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.media.projection.MediaProjection;
import android.media.projection.MediaProjectionManager;
import android.os.Bundle;
import android.os.IBinder;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import androidx.activity.EdgeToEdge;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    //请求码
    private final static int REQUEST_CODE = 101;
    //权限请求码
    private final static int PERMISSION_REQUEST_CODE = 1101;
    //录屏工具
    MediaProjectionManager mediaProjectionManager;
    MediaProjection mediaProjection;
    //开始按钮，停止按钮
    Button btn_start_recorder;
    Button btn_stop_recorder;
    //获取录屏范围参数
    DisplayMetrics metrics;
    //录屏服务
    ScreenRecordService screenRecordService;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_main);
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });

        //实例化按钮
        btn_start_recorder = findViewById(R.id.btn_start_recorder);
        btn_stop_recorder = findViewById(R.id.btn_stop_recorder);
        //点击按钮，请求录屏
        btn_start_recorder.setOnClickListener(this);
        btn_stop_recorder.setOnClickListener(this);
    }

    //权限检查，连接录屏服务
    public void checkPermission() {
        //调用检查权限接口进行权限检查
        if ((ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) && (ContextCompat.checkSelfPermission(MainActivity.this,
                Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED)) {
            //如果没有权限，获取权限
            //调用请求权限接口进行权限申请
            ActivityCompat.requestPermissions(this, new String[]{
                    Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO}, PERMISSION_REQUEST_CODE);
        } else {
            //有权限，连接录屏服务，进行录屏
            connectService();
        }
    }

    //没有权限，去请求权限后，需要判断用户是否同意权限请求
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == PERMISSION_REQUEST_CODE) {
            //请求码相同
            if (grantResults.length > 0 &&
                    (grantResults[0] != PackageManager.PERMISSION_GRANTED ||
                            grantResults[1] != PackageManager.PERMISSION_GRANTED)) {
                //如果结果都存在，但是至少一个没请求成功，弹出提示
                Toast.makeText(MainActivity.this, "请同意必须的应用权限，否则无法正常使用该功能！", Toast.LENGTH_SHORT).show();
            } else if (grantResults.length > 0) {
                //如果结果都存在，两个权限都申请成功，连接服务，启动录屏
                Toast.makeText(MainActivity.this, "权限申请成功，用户同意！", Toast.LENGTH_SHORT).show();
                connectService();

            }
        }
    }

    //连接服务
    public void connectService() {
        //通过intent为中介绑定Service，会自动create
        Intent intent = new Intent(this, ScreenRecordService.class);
        //绑定过程连接，选择绑定模式
        bindService(intent, serviceConnection, BIND_AUTO_CREATE);
        //获取到服务，初始化录屏管理者
        mediaProjectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);
        //通过管理者，创建录屏请求，通过Intent
        Intent captureIntent = mediaProjectionManager.createScreenCaptureIntent();
        //将请求码作为标识一起发送，调用该接口，需有返回方法
        startActivityForResult(captureIntent, REQUEST_CODE);
    }

    //连接服务成功与否，具体连接过程
    //调用连接接口，实现连接，回调连接结果
    private final ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            //服务连接成功，需要通过Binder获取服务，达到Activity和Service通信的目的
            //获取Binder
            ScreenRecordService.ScreenRecordBinder binder = (ScreenRecordService.ScreenRecordBinder) iBinder;
            //通过Binder获取Service
            screenRecordService = binder.getScreenRecordService();

        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            //连接失败
            Toast.makeText(MainActivity.this, "录屏服务未连接成功，请重试！", Toast.LENGTH_SHORT).show();
        }
    };

    @Override
    //返回方法，获取返回的信息
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        //首先判断请求码是否一致，结果是否ok
        if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) {
            //录屏请求成功，使用工具MediaProjection录屏
            //从发送获得的数据和结果中获取该工具
            assert data != null;
            mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, data);
            //将该工具给Service，并一起传过去需要录制的屏幕范围的参数
            if (screenRecordService != null) {
                screenRecordService.setMediaProjection(mediaProjection);
                //获取录屏屏幕范围参数
                metrics = new DisplayMetrics();
                getWindowManager().getDefaultDisplay().getMetrics(metrics);
                Log.d("Main", "width:" + metrics.widthPixels + ",height:" + metrics.heightPixels);
                int width = metrics.widthPixels;
                int height = metrics.heightPixels;
                if (height % 2 == 1) {
                    //奇数
                    height = height - 1;
                }
                screenRecordService.setConfig(width, height, metrics.densityDpi);
            }
        }
    }

    @SuppressLint("NonConstantResourceId")
    @Override
    //点击事件
    public void onClick(View view) {
        if (view.getId() == R.id.btn_start_recorder) {
            //点击请求录屏后，第一件事，检查权限
            checkPermission();
            //参数传过去以后，如果在录制，提示
            if (screenRecordService != null && screenRecordService.isRunning()) {
                Toast.makeText(MainActivity.this, "当前正在录屏，请不要重复点击哦！", Toast.LENGTH_SHORT).show();
            } else if (screenRecordService != null && !screenRecordService.isRunning()) {
                //没有录制，就开始录制，弹出提示，返回主界面开始录制
                if (screenRecordService.startRecord()) {
                    //返回主界面开始录制
                    setToBackground();
                }

            } else if (screenRecordService == null) {
                connectService();
            }
        } else if (view.getId() == R.id.btn_stop_recorder) {
            if (screenRecordService != null && !screenRecordService.isRunning()) {
                //没有在录屏，无法停止，弹出提示
                Toast.makeText(MainActivity.this, "您还没有录屏，无法停止，请先开始录屏吧！", Toast.LENGTH_SHORT).show();
            } else if (screenRecordService != null && screenRecordService.isRunning()) {
                //正在录屏，点击停止，停止录屏
                screenRecordService.stopRecord();
            }
        }
    }

    //返回主界面开始录屏，相当于home键
    private void setToBackground() {
        //主页面的Intent
        Intent home = new Intent(Intent.ACTION_MAIN);
        //设置清除栈顶的启动模式
        home.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        //匹配符号
        home.addCategory(Intent.CATEGORY_HOME);
        //转换界面，隐式匹配，显示调用
        startActivity(home);
    }

    //当应用结束的时候，需要解除绑定服务，防止造成内存泄漏
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(serviceConnection);
    }

}